/*
 * DIMACSCollectionParser.hpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DIMACSCOLLECTIONPARSER_HPP_
#define DIMACSCOLLECTIONPARSER_HPP_

#include <iostream>
#include <string>
#include <list>
#include <utility>
#include <iterator>
#include "bfr/DIMACSParser.hpp"
#include "bfr/ClauseSet.hpp"

namespace bfr {

class DIMACSCollectionIterator :
        public std::iterator<std::output_iterator_tag, ClauseSet*> {
    public:
        DIMACSCollectionIterator(size_t size,
                                    std::istream *stream,
                                    DIMACSParser *parser,
                                    size_t pos=0);

        DIMACSCollectionIterator(const DIMACSCollectionIterator &other);
        DIMACSCollectionIterator&
            operator=(const DIMACSCollectionIterator &other);

        DIMACSCollectionIterator& operator++();
        DIMACSCollectionIterator operator++(int);
        bool operator==(const DIMACSCollectionIterator& rhs);
        bool operator!=(const DIMACSCollectionIterator& rhs);
        bool operator<(const DIMACSCollectionIterator& rhs);
        std::pair<ClauseSet*, size_t> operator*();

    private:
        size_t size;
        size_t pos;
        std::istream *stream;
        DIMACSParser *parser;
};

/**
 * This class can be used to parse a collection of DIMACS files.
 *
 * If you have many DNFs / CNFs in DIMACS format it is often useful
 * to create one big file with all DIMACS content instead of many
 * single files.
 *
 * This class can be used for this purpose.
 *
 * It assumes that the DNFs are all just listed one by one.
 *
 * For an example see one of the enumeration files I've uploaded at the
 * project homepage.
 */
class DIMACSCollectionParser {
    public:
        /**
         * Constructor.
         */
        DIMACSCollectionParser(std::istream *in, size_t numSets);

        /**
         * Destructor.
         */
        ~DIMACSCollectionParser();

        typedef DIMACSCollectionIterator const_iterator;

        const_iterator begin() const;
        const_iterator end() const;

    private:
        // parser that is used to read the DIMACS descriptions.
        std::istream *stream;
        size_t numSets;
        DIMACSParser *dp;

        /**
         * Should not be used, therefore private.
         */
        DIMACSCollectionParser()
            : stream(0), numSets(0), dp(0) { }
};

}

#endif  // DIMACSCOLLECTIONPARSER_HPP_
